home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 1.iso / HENSA / MATHS / PLPLOT / PLPLOT.ZIP / src / plsym.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-07-21  |  7.4 KB  |  290 lines

  1. /* $Id: plsym.c,v 1.12 1994/07/21 10:11:42 mjl Exp $
  2.  * $Log: plsym.c,v $
  3.  * Revision 1.12  1994/07/21  10:11:42  mjl
  4.  * Added a fast point draw capability: if code=-1 is given to plpoin or
  5.  * plpoin3, instead of drawing a Hershey font character it draws a point
  6.  * using simply a move and draw.  This is at least 4X faster.
  7.  *
  8.  * Revision 1.11  1994/07/20  06:09:50  mjl
  9.  * Changed syntax of the new 3d function plpoin3() to be more like plpoin(),
  10.  * and moved to this file.
  11.  *
  12.  * Revision 1.10  1994/06/30  18:22:21  mjl
  13.  * All core source files: made another pass to eliminate warnings when using
  14.  * gcc -Wall.  Lots of cleaning up: got rid of includes of math.h or string.h
  15.  * (now included by plplot.h), and other minor changes.  Now each file has
  16.  * global access to the plstream pointer via extern; many accessor functions
  17.  * eliminated as a result.
  18.  *
  19.  * Revision 1.9  1994/03/23  08:34:53  mjl
  20.  * All external API source files: replaced call to plexit() on simple
  21.  * (recoverable) errors with simply printing the error message (via
  22.  * plabort()) and returning.  Should help avoid loss of computer time in some
  23.  * critical circumstances (during a long batch run, for example).
  24. */
  25.  
  26. /*    plsym.c
  27.  
  28.     Point and symbol plotting routines.
  29. */
  30.  
  31. #include "plplotP.h"
  32. #include <float.h>
  33.  
  34. extern short int *fntlkup;
  35. extern short int numberfonts, numberchars;
  36.  
  37. /*----------------------------------------------------------------------*\
  38.  * void plsym()
  39.  *
  40.  * Plots array y against x for n points using Hershey symbol "code".
  41. \*----------------------------------------------------------------------*/
  42.  
  43. void
  44. c_plsym(PLINT n, PLFLT *x, PLFLT *y, PLINT code)
  45. {
  46.     PLINT i;
  47.  
  48.     if (plsc->level < 3) {
  49.     plabort("plsym: Please set up window first");
  50.     return;
  51.     }
  52.     if (code < 0) {
  53.     plabort("plsym: Invalid code");
  54.     return;
  55.     }
  56.  
  57.     for (i = 0; i < n; i++)
  58.     plhrsh(code, plP_wcpcx(x[i]), plP_wcpcy(y[i]));
  59. }
  60.  
  61. /*----------------------------------------------------------------------*\
  62.  * void plpoin()
  63.  *
  64.  * Plots array y against x for n points using ASCII code "code".
  65.  *
  66.  * code=-1 means try to just draw a point.  Right now it's just a move and
  67.  * a draw at the same place.  Not ideal, since a sufficiently intelligent
  68.  * output device may optimize it away, or there may be faster ways of
  69.  * doing it.  This is OK for now, though, and offers a 4X speedup over
  70.  * drawing a Hershey font "point" (which is actually diamond shaped and
  71.  * therefore takes 4 strokes to draw).
  72. \*----------------------------------------------------------------------*/
  73.  
  74. void
  75. c_plpoin(PLINT n, PLFLT *x, PLFLT *y, PLINT code)
  76. {
  77.     PLINT i, sym, font, col;
  78.  
  79.     if (plsc->level < 3) {
  80.     plabort("plpoin: Please set up window first");
  81.     return;
  82.     }
  83.     if (code < -1 || code > 127) {
  84.     plabort("plpoin: Invalid code");
  85.     return;
  86.     }
  87.  
  88.     if (code == -1) {
  89.     for (i = 0; i < n; i++)
  90.         pljoin(x[i], y[i], x[i], y[i]);
  91.     }
  92.     else {
  93.     plP_gatt(&font, &col);
  94.     sym = *(fntlkup + (font - 1) * numberchars + code);
  95.  
  96.     for (i = 0; i < n; i++)
  97.         plhrsh(sym, plP_wcpcx(x[i]), plP_wcpcy(y[i]));
  98.     }
  99. }
  100.  
  101. /*----------------------------------------------------------------------*\
  102.  * void plpoin3(n, x, y, z, code)
  103.  *
  104.  * Draws a series of points in 3 space.  Setup similar to plline3().
  105. \*----------------------------------------------------------------------*/
  106.  
  107. void
  108. c_plpoin3(PLINT n, PLFLT *x, PLFLT *y, PLFLT *z, PLINT code)
  109. {
  110.     PLINT i, sym, font, col;
  111.     PLFLT u, v;
  112.  
  113.     if (plsc->level < 3) {
  114.     plabort("plpoin3: Please set up window first");
  115.     return;
  116.     }
  117.     if (code < -1 || code > 127) {
  118.     plabort("plpoin3: Invalid code");
  119.     return;
  120.     }
  121.  
  122.     if (code == -1) {
  123.     for (i = 0; i < n; i++) {
  124.         u = plP_wcpcx(plP_w3wcx( x[i], y[i], z[i] ));
  125.         v = plP_wcpcy(plP_w3wcy( x[i], y[i], z[i] ));
  126.         plP_movphy(u,v);
  127.         plP_draphy(u,v);
  128.     }
  129.     }
  130.     else {
  131.     plP_gatt(&font, &col);
  132.     sym = *(fntlkup + (font - 1) * numberchars + code);
  133.  
  134.     for( i=0; i < n; i++ ) {
  135.         u = plP_wcpcx(plP_w3wcx( x[i], y[i], z[i] ));
  136.         v = plP_wcpcy(plP_w3wcy( x[i], y[i], z[i] ));
  137.         plhrsh(sym, u, v);
  138.     }
  139.     }
  140.     return;
  141. }
  142.  
  143. /*----------------------------------------------------------------------*\
  144.  * void plhrsh()
  145.  *
  146.  * Writes the Hershey symbol "ch" centred at the physical
  147.  * coordinate (x,y).
  148. \*----------------------------------------------------------------------*/
  149.  
  150. void
  151. plhrsh(PLINT ch, PLINT x, PLINT y)
  152. {
  153.     PLINT cx, cy, k, penup;
  154.     SCHAR *xygrid;
  155.     PLFLT scale, xscale, yscale;
  156.  
  157.     penup = 1;
  158.     scale = 0.05 * plsc->symht;
  159.  
  160.     if ( ! plcvec(ch, &xygrid)) {
  161.     plP_movphy(x, y);
  162.     return;
  163.     }
  164.  
  165.     /* Compute how many physical pixels correspond to a character pixel */
  166.  
  167.     xscale = scale * plsc->xpmm;
  168.     yscale = scale * plsc->ypmm;
  169.  
  170.     k = 4;
  171.     for (;;) {
  172.     cx = xygrid[k++];
  173.     cy = xygrid[k++];
  174.     if (cx == 64 && cy == 64) {
  175.         plP_movphy(x, y);
  176.         return;
  177.     }
  178.     else if (cx == 64 && cy == 0)
  179.         penup = 1;
  180.     else {
  181.         if (penup != 0) {
  182.         plP_movphy(ROUND(x + xscale * cx), ROUND(y + yscale * cy));
  183.         penup = 0;
  184.         }
  185.         else
  186.         plP_draphy(ROUND(x + xscale * cx), ROUND(y + yscale * cy));
  187.     }
  188.     }
  189. }
  190.  
  191. /*----------------------------------------------------------------------*\
  192.  * void plarrows()
  193.  *
  194.  * simple arrow plotter
  195.  * copyright 1993 Wesley Ebisuzaki
  196.  *
  197.  * an arrow is defined by its location (x, y) and its direction (u, v)
  198.  *
  199.  * inputs:
  200.  *   u[i], v[i]      arrow's horizontal and vertical projection
  201.  *   x[i], y[i]      arrow's location (world coordinates)
  202.  *   n               number of arrows to draw
  203.  *   scale           > 0  scaling factor for arrows
  204.  *                   0    default scaling factor
  205.  *                   < 0  default scaling factor * (-scale)
  206.  *   dx, dy          distance between arrows
  207.  *                   used when calculating the default arrow scaling
  208.  *                   so that arrows don't overlap
  209.  *
  210. \*----------------------------------------------------------------------*/
  211.  
  212. #define SCALE0 2.0
  213.  
  214. /* definition of original arrow: 2 line segments */
  215.  
  216. static PLFLT arrow_x[4] = {0.5, -0.5, -0.27, -0.5};
  217. static PLFLT arrow_y[4] = {0.0, 0.0, 0.0, 0.20};
  218.  
  219. void 
  220. plarrows(PLFLT *u, PLFLT *v, PLFLT *x, PLFLT *y, PLINT n,
  221.      PLFLT scale, PLFLT dx, PLFLT dy) 
  222. {
  223.     PLFLT uu, vv;
  224.     PLINT i, j;
  225.     PLINT px0, py0, dpx, dpy;
  226.     PLINT a_x[4], a_y[4];
  227.     PLFLT max_u, max_v;
  228.     double t;
  229.  
  230.     if (n <= 0) return;
  231.  
  232.     if (scale <= 0.0) {
  233.     /* automatic scaling */
  234.     /* find max / min values of data */
  235.     max_u = u[0];
  236.     max_v = v[0];
  237.     for (i = 1; i < n; i++) {
  238.         t = fabs((double) u[i]);
  239.         max_u = t > max_u ? t : max_u;
  240.         t = fabs((double) v[i]);
  241.         max_v = t > max_v ? t : max_v;
  242.     }
  243.  
  244.     /* measure distance in grid boxs */
  245.     max_u = max_u / fabs( (double) dx);
  246.     max_v = max_v / fabs( (double) dy);
  247.  
  248.     t = (max_u > max_v ? max_u : max_v);
  249.     t = SCALE0 / t;
  250.     if (scale < 0) {
  251.         scale = -scale * t;
  252.     }
  253.     else {
  254.         scale = t;
  255.     }
  256.     }
  257. #ifdef DEBUG
  258.     fprintf(stderr, "scale factor=%lf n=%d\n", scale,n);
  259. #endif
  260.  
  261.     for (i = 0; i < n; i++) {
  262.     uu = scale * u[i];
  263.     vv = scale * v[i];
  264.     if (uu == 0.0 && uu == 0.0) continue;
  265.  
  266.     /* conversion to physical coordinates */
  267.     px0 = plP_wcpcx(x[i]);
  268.     py0 = plP_wcpcy(y[i]);
  269.  
  270. #ifdef DEBUG
  271.     fprintf(stderr, "%f %f %d %d\n",x[i],y[i],px0,py0);
  272. #endif
  273.     dpx = plP_wcpcx(x[i] + 0.5*uu) - px0;
  274.     dpy = plP_wcpcy(y[i] + 0.5*vv) - py0;
  275.  
  276.     /* tranform arrow -> a */
  277.     for (j = 0; j < 4; j++) {
  278.         a_x[j] = arrow_x[j] * dpx -
  279.         arrow_y[j] * dpy + px0;
  280.         a_y[j] = arrow_x[j] * dpy +
  281.         arrow_y[j] * dpx + py0;
  282.     }
  283.     /* draw the arrow */
  284.     plP_movphy(a_x[0], a_y[0]);
  285.     plP_draphy(a_x[1], a_y[1]);
  286.     plP_movphy(a_x[2], a_y[2]);
  287.     plP_draphy(a_x[3], a_y[3]);
  288.     }
  289. }
  290.